package com.xnyzc.lhy.mis.service.impl.cms.vehicle;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xnyzc.lhy.common.component.convert.DateToStringConverter;
import com.xnyzc.lhy.common.constant.MessageConstant;
import com.xnyzc.lhy.common.entity.Rv;
import com.xnyzc.lhy.common.exception.PangException;
import com.xnyzc.lhy.common.global.Configuration;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.penum.cms.EVehicleType;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.common.util.IDUtil;
import com.xnyzc.lhy.common.util.TokenUtil;
import com.xnyzc.lhy.common.util.validation.RegularValidation;
import com.xnyzc.lhy.mis.entity.area.OaSysArea;
import com.xnyzc.lhy.mis.entity.dictionaries.OaSysDict;
import com.xnyzc.lhy.mis.entity.param.cms.vehicle.CmsOaVehicleImport;
import com.xnyzc.lhy.mis.entity.result.vehicle.VehicleImportRecordResult;
import com.xnyzc.lhy.mis.entity.system.OaSysGlobalConfig;
import com.xnyzc.lhy.mis.entity.vehicle.OaDDriverVehicle;
import com.xnyzc.lhy.mis.entity.vehicle.OaSysVehicle;
import com.xnyzc.lhy.mis.entity.vehicle.OaSysVehicleMdict;
import com.xnyzc.lhy.mis.entity.vehicle.OaVehicleImportRecord;
import com.xnyzc.lhy.mis.mapper.area.OaSysAreaMapper;
import com.xnyzc.lhy.mis.mapper.dictionaries.OaSysDictMapper;
import com.xnyzc.lhy.mis.mapper.system.OaSysGlobalConfigMapper;
import com.xnyzc.lhy.mis.mapper.vehicle.OaDDriverVehicleMapper;
import com.xnyzc.lhy.mis.mapper.vehicle.OaSysVehicleMdictMapper;
import com.xnyzc.lhy.mis.mapper.vehicle.OaVehicleImportRecordMapper;
import com.xnyzc.lhy.mis.service.cms.vehicle.ICmsVehicleImportService;
import com.xnyzc.lhy.mis.service.cms.vehicle.IOaDDriverVehicleService;
import com.xnyzc.lhy.mis.service.cms.vehicle.IOaSysVehicleService;
import com.xnyzc.lhy.mis.service.oss.IOaOssFileClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Pattern;

/**
 * @Description 车辆导入
 * @Author wangshuo
 * @Date 2019-12-04 15:48
 **/
@Service
public class CmsVehicleImportServiceImpl implements ICmsVehicleImportService {

    @Autowired
    private IOaSysVehicleService iOaSysVehicleService;

    @Autowired
    private IOaDDriverVehicleService iOaDDriverVehicleService;

    @Autowired
    private OaSysVehicleMdictMapper oaSysVehicleMdictMapper;

    @Autowired
    private OaSysDictMapper oaSysDictMapper;

    @Autowired
    private OaSysAreaMapper oaSysAreaMapper;

    @Autowired
    private OaDDriverVehicleMapper oaDDriverVehicleMapper;

    @Autowired
    private OaSysGlobalConfigMapper sysGlobalConfigMapper;

    @Autowired
    private OaVehicleImportRecordMapper oaVehicleImportRecordMapper;

    @Autowired
    private IOaOssFileClientService iOaOssFileClientService;

    /**
     * 车辆导入
     *
     * @param sysUserId            后台用户
     * @param tag                  租户
     * @param cmsVehicleImportList 表格数据
     * @return
     */
    @Override
    public String vehicleImport(Long sysUserId, String tag, String clientId, List<CmsOaVehicleImport> cmsVehicleImportList) {
        Date date = new Date();
        Map<String, Integer> vehNoMap = new HashMap<>();
        Map<String, Integer> vehFrameNumberMap = new HashMap<>();
        Map<String, Integer> formatVehNoMap = new HashMap<>();
        Map<String, Integer> formatFrameMap = new HashMap<>();
        List<OaSysVehicle> oaSysVehiclesList = new ArrayList<>();
        // 查重
        List<OaSysVehicle> oaSysVehicles = iOaSysVehicleService.list(Wrappers.<OaSysVehicle>lambdaQuery().eq(OaSysVehicle::getTag, tag));
        // 对比数据库重复车牌号
        StringBuffer repeatVehNo = new StringBuffer();
        boolean isRepeatVehNo = false;
        repeatVehNo.append(MessageConstant.REPEAT_VEHICLE_NO).append(":");
        // 对比数据库重复车架号
        StringBuffer repeatVehFrame = new StringBuffer();
        boolean isRepeatVehFrame = false;
        repeatVehFrame.append(MessageConstant.REPEAT_VEHICLE_FRAME).append(":");
        StringBuffer formatVehNo = new StringBuffer();
        boolean isFormatVehNo = false;
        formatVehNo.append(MessageConstant.FORMAT_VEHNO).append(":");
        StringBuffer formatVehFrame = new StringBuffer();
        boolean isFormatVehFrame = false;
        formatVehFrame.append(MessageConstant.FORMAT_VEHFRAME).append(":");

        QueryWrapper<OaSysDict> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(OaSysDict.TYPE, "vegicle_color_type");
        //查询车辆颜色字典表
        List<OaSysDict> dictList = oaSysDictMapper.selectList(queryWrapper);
        HashMap<String, String> dictMap=new HashMap<>();
        for (int i = 0; i < dictList.size(); i++) {
            dictMap.put(dictList.get(i).getLabel(),dictList.get(i).getValue());
        }
        List<OaSysArea> areaList = oaSysAreaMapper.selectList(null);
        boolean isRepeatArea = false;
        for (CmsOaVehicleImport cmsVehicleImport : cmsVehicleImportList) {
             // 校验
            verify(vehNoMap,vehFrameNumberMap,cmsVehicleImport);
            //校验颜色
            if (!dictMap.containsKey(cmsVehicleImport.getVehColor())){
                throw PangException.create(EErrorCode.nullColor);
            }
            // 去空格
            cmsVehicleImport.setVehNo(cmsVehicleImport.getVehNo().replaceAll(" ",""));
            cmsVehicleImport.setVehFrameNumber(cmsVehicleImport.getVehFrameNumber().replaceAll(" ",""));
            //cmsVehicleImport.setVehEngineNumber(cmsVehicleImport.getVehEngineNumber().replaceAll(" ",""));
            cmsVehicleImport.setVehCityName(cmsVehicleImport.getVehCityName().replaceAll(" ",""));

            Pattern frameNumberPattern = Pattern.compile(Configuration.FRAME_REGULAR);
            boolean frameNumber = Pattern.matches(frameNumberPattern.pattern(), String.valueOf(cmsVehicleImport.getVehFrameNumber()));
            if (!frameNumber) {
                formatFrameMap.put(cmsVehicleImport.getVehFrameNumber(), 1);
                isFormatVehFrame = true;
                formatVehFrame.append(cmsVehicleImport.getVehFrameNumber()).append("、");
            }
            //正则验证车牌号
            boolean vehNoValidationOne = RegularValidation.validationData(RegularValidation.CASE_VEHNO, cmsVehicleImport.getVehNo());
            boolean vehNoValidationTwo = RegularValidation.validationData(RegularValidation.CASE_NEWVEHNO, cmsVehicleImport.getVehNo());

            if (!vehNoValidationOne && !vehNoValidationTwo) {
                formatVehNoMap.put(cmsVehicleImport.getVehNo(), 1);
                isFormatVehNo = true;//验证车牌号不通过
                formatVehNo.append(cmsVehicleImport.getVehNo()).append("、");
            }
            vehNoMap.put(cmsVehicleImport.getVehNo(), 1);
            vehFrameNumberMap.put(cmsVehicleImport.getVehFrameNumber(),1);
            for (OaSysVehicle vehicle : oaSysVehicles) {
                if (cmsVehicleImport.getVehFrameNumber().equals(vehicle.getVehFrameNumber())) {
                    isRepeatVehFrame = true;
                    repeatVehFrame.append(cmsVehicleImport.getVehFrameNumber()).append("、");
                    break;
                }
                if (cmsVehicleImport.getVehNo().equals(vehicle.getVehNo())) {
                    isRepeatVehNo = true;
                    repeatVehNo.append(cmsVehicleImport.getVehNo()).append("、");
                    break;
                }
            }
            int isArea=0;
            for (OaSysArea area : areaList) {
                if (cmsVehicleImport.getVehCityName().equals(area.getName())) {
                    isArea=1;
                    break;
                }
            }
            if(isArea==0){
                isRepeatArea = true;
            }
            oaSysVehiclesList.add(this.insertOaSysVehicle(areaList,dictList,cmsVehicleImport,sysUserId, tag, date));
        }
        disposeData(cmsVehicleImportList,repeatVehNo,repeatVehFrame,formatVehNo,formatVehFrame,
                isRepeatVehNo,isRepeatVehFrame,isFormatVehNo,isFormatVehFrame,oaSysVehiclesList,isRepeatArea);
        return EErrorCode.impSuccess.getDesc();
    }

    /**
     * 校验
     */
    public void verify(Map<String, Integer> vehNoMap, Map<String, Integer> vehFrameNumberMap,CmsOaVehicleImport cmsVehicleImport){
        if (CheckUtil.objIsEmpty(cmsVehicleImport.getVehNo(),cmsVehicleImport.getVehFrameNumber(),cmsVehicleImport.getVehColor())) {//cmsVehicleImport.getVehicleModel()
            throw PangException.create(EErrorCode.impVehicleNull);
        }
        if(vehFrameNumberMap.containsKey(cmsVehicleImport.getVehFrameNumber())){
            throw PangException.create(EErrorCode.impRepeatVehFrame);
        }
        if (vehNoMap.containsKey(cmsVehicleImport.getVehNo())) {
            throw PangException.create(EErrorCode.impRepeatVeh);
        }
    }

    /**
     * 处理数据
     */
    public void disposeData(List<CmsOaVehicleImport> cmsOaVehicleImportList,StringBuffer repeatVehNo,StringBuffer repeatVehFrame,StringBuffer formatVehNo,StringBuffer formatVehFrame,
                            boolean isRepeatVehNo,boolean isRepeatVehFrame,boolean isFormatVehNo,boolean isFormatVehFrame,
                            List<OaSysVehicle> vehicleList,boolean isRepeatArea){
        repeatVehNo= repeatVehNo.deleteCharAt(repeatVehNo.length() - 1);
        repeatVehFrame=repeatVehFrame.deleteCharAt(repeatVehFrame.length() -1);
        formatVehNo=formatVehNo.deleteCharAt(formatVehNo.length()-1);
        formatVehFrame=formatVehFrame.deleteCharAt(formatVehFrame.length()-1);
        if (isFormatVehNo) {
            throw PangException.create(EErrorCode.formatVehNo, formatVehNo.toString());
        }
        if (isFormatVehFrame) {
            throw PangException.create(EErrorCode.formatVehframe, formatVehFrame.toString());
        }
        if(isRepeatVehNo){
            throw PangException.create(EErrorCode.impDBRepeatVehNo, repeatVehNo.toString());
        }
        if(isRepeatVehFrame){
            throw PangException.create(EErrorCode.impDBRepeatVehFrame, repeatVehFrame.toString());
        }
        if(isRepeatArea){
            throw PangException.create(EErrorCode.formatVehCityName, EErrorCode.formatVehCityName.getDesc());
        }
        boolean validation = this.iOaSysVehicleService.saveBatch(vehicleList);
        if (!validation) {
            throw PangException.create(EErrorCode.impFailure);
        }
        List<String> vehCode=new ArrayList<>();
        for(CmsOaVehicleImport userImport:cmsOaVehicleImportList){
            vehCode.add(userImport.getVehicleModel());
        }
        // 修改关联
        QueryWrapper<OaSysVehicleMdict> queryWrapper = new QueryWrapper<>();
        queryWrapper.in(OaSysVehicleMdict.CODE, vehCode);
        List<OaSysVehicleMdict> mdictList = oaSysVehicleMdictMapper.selectList(queryWrapper);
        for(OaSysVehicleMdict mdict:mdictList){
            mdict.setIsRelation(1);
            mdict.setUpdateTime(new Date());
            oaSysVehicleMdictMapper.updateById(mdict);
        }

    }

    private OaDDriverVehicle insertDriverVehicle(List<OaSysVehicle> oaSysVehiclesList,CmsOaVehicleImport cmsVehicleImport,Long sysUserId,String tag, Date date) {
        Long vehId=0L;
        for(OaSysVehicle vehicle:oaSysVehiclesList){
            if(vehicle.getVehNo().equals(cmsVehicleImport.getVehNo())){
                vehId=vehicle.getVehicleId();
            }
        }
        OaDDriverVehicle driverVehicle=new OaDDriverVehicle();
        driverVehicle.setVehicleId(vehId);
        driverVehicle.setLinkedId(IDUtil.nextId());
        driverVehicle.setDriverId(0L);
        driverVehicle.setCreateTime(date);
        driverVehicle.setCreateUser(sysUserId);
        driverVehicle.setUpdateTime(date);
        driverVehicle.setIsUse(1);
        driverVehicle.setTag(tag);
        driverVehicle.setUpdateUser(sysUserId);
        return driverVehicle;
    }

    private OaSysVehicle insertOaSysVehicle(List<OaSysArea> areaList, List<OaSysDict> dictList, CmsOaVehicleImport cmsVehicleImport, Long sysUserId, String tag, Date date) {
        OaSysVehicle vehicle=new OaSysVehicle();
        Long vehId=IDUtil.nextId();
        vehicle.setVehicleId(vehId);
        vehicle.setVehFrameNumber(cmsVehicleImport.getVehFrameNumber());
        vehicle.setVehNo(cmsVehicleImport.getVehNo());
        vehicle.setVehEngineNumber(cmsVehicleImport.getVehEngineNumber());
        vehicle.setCode("");
        //转化车系编号字符串集合
        String[] vehicleModels =  cmsVehicleImport.getVehicleModel().split("-");
        if(vehicleModels.length != 3){
            throw PangException.create(EErrorCode.carModelError);
        }
        // 查询车辆字典表的信息
        QueryWrapper<OaSysVehicleMdict> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(OaSysVehicleMdict.NAME,vehicleModels[2]);
        List<OaSysVehicleMdict> oaSysVehicleMdicts = oaSysVehicleMdictMapper.selectList(queryWrapper);
        for (OaSysVehicleMdict info : oaSysVehicleMdicts){
            if(info.getName().equals(vehicleModels[2])){
                vehicle.setCode(info.getCode());
                vehicle.setVehType(info.getVehicleType());
            }
        }
        vehicle.setVehColor(0);
        vehicle.setVehStatus(0);
        vehicle.setDrivingLicenseNumber(cmsVehicleImport.getDrivingLicenseNumber());
        vehicle.setTransportCertificateNumber(cmsVehicleImport.getTransportCertificateNumber());
        vehicle.setVehSeatsNumber(Integer.parseInt(cmsVehicleImport.getVehSeatsNumber()));
        for(OaSysArea dict:areaList){
            if(dict.getName().equals(cmsVehicleImport.getVehCityName())){
                vehicle.setCityCode(dict.getAdCode());
                break;
            }
        }
        for(OaSysDict dict:dictList){
            if(dict.getLabel().equals(cmsVehicleImport.getVehColor())){
                vehicle.setVehColor(Integer.valueOf(dict.getValue()));
                break;
            }
        }
        if(cmsVehicleImport.getVehFuelType().equals(EVehicleType.vehFuelTypeHybird.getDesc())){
            vehicle.setVehFuelType(EVehicleType.vehFuelTypeHybird.getValue());
        }else if(cmsVehicleImport.getVehFuelType().equals(EVehicleType.vehFuelTypeElectric.getDesc())){
            vehicle.setVehFuelType(EVehicleType.vehFuelTypeElectric.getValue());
        }else if(cmsVehicleImport.getVehFuelType().equals(EVehicleType.vehFuelTypeDiesel.getDesc())){
            vehicle.setVehFuelType(EVehicleType.vehFuelTypeDiesel.getValue());
        }else if(cmsVehicleImport.getVehFuelType().equals(EVehicleType.vehFuelTypeTanker.getDesc())){
            vehicle.setVehFuelType(EVehicleType.vehFuelTypeTanker.getValue());
        }else{
            vehicle.setVehFuelType(EVehicleType.vehFuelTypePlugIn.getValue());
        }
        vehicle.setVehicleOwnerId(0L);
        vehicle.setCreateTime(date);
        vehicle.setCreateUser(sysUserId);
        vehicle.setUpdateTime(date);
        vehicle.setTag(tag);
        vehicle.setUpdateUser(sysUserId);
        return vehicle;
    }

    /**
     * 获取下载模板数据
     *
     * @return
     */
    @Override
    public Rv getVehicleDownloadTemplate() {
        List<OaSysGlobalConfig> oaSysGlobalConfigs = sysGlobalConfigMapper.selectList(null);
        if (CheckUtil.objIsEmpty(oaSysGlobalConfigs)) {
            return Rv.wrap(EErrorCode.unData);
        }
        OaSysGlobalConfig config = oaSysGlobalConfigs.get(0);
        Map<String, Long> map = new HashMap<>();
        map.put("importId", config.getVehicleImportFileId());
        return Rv.wrap(EErrorCode.success, map);
    }

    /**
     * 添加车辆导入记录
     * */
    @Override
    public Rv addVehicleImportRecord(OaVehicleImportRecord vehicleImportRecord) {
        Long sysUserId = TokenUtil.getTokenUserId();
        vehicleImportRecord.setRecordId(IDUtil.nextId());
        vehicleImportRecord.setOperationId(sysUserId);
        vehicleImportRecord.setCreateUser(sysUserId);
        vehicleImportRecord.setUpdateUser(sysUserId);
        vehicleImportRecord.setCreateTime(new Date());
        vehicleImportRecord.setUpdateTime(new Date());
        oaVehicleImportRecordMapper.insert(vehicleImportRecord);
        return  Rv.wrap(EErrorCode.success);
    }

    /**
     * 车辆导入历史
     * @return
     */
    @Override
    public Rv getQueryVehicleImportRecord(Integer size,Integer page) {
        if(CheckUtil.objIsEmpty(size,page)){
            return Rv.wrap(EErrorCode.missingArg);
        }
        IPage iPage = new Page();
        iPage.setSize(size);
        iPage.setCurrent(page);
        List<VehicleImportRecordResult> importRecordsList  = oaVehicleImportRecordMapper.queryVehicleImportRecord(iPage);
        if(!importRecordsList.isEmpty()){
            for(VehicleImportRecordResult importRecord:importRecordsList){
                if(CheckUtil.strIsEmpty(importRecord.getFilePath())){
                    Rv rv=iOaOssFileClientService.getFileUrlCos(importRecord.getFileId());
                    if (CheckUtil.objIsNotEmpty(rv.getData())) {
                        importRecord.setFilePath(((Map) rv.getData()).get("fileUrl").toString());
                    } else {
                        importRecord.setFilePath("");
                    }
                }
                importRecord.setCreateTimeStr(new DateToStringConverter().convert(importRecord.getCreateTime()));
            }
        }
        iPage.setRecords(importRecordsList);
        return  Rv.wrap(EErrorCode.success,iPage);
    }

    /**
     * 查询车字典
     *
     * @return
     */
    private List<OaSysVehicleMdict> findVehicleMdict(List<String> inList, String findField) {
        //查询车字典数据
        QueryWrapper<OaSysVehicleMdict> queryWrapper = new QueryWrapper<>();
        queryWrapper.in(findField, inList);
        queryWrapper.select(OaSysVehicleMdict.MDICT_ID, OaSysVehicleMdict.PARENT_ID, OaSysVehicleMdict.CODE, OaSysVehicleMdict.NAME);
        return oaSysVehicleMdictMapper.selectList(queryWrapper);
    }

}
